#include "nameserver/NameSrvController.h"

namespace zeroplus::mq
{
    NameSrvController::NameSrvController(const std::string &uri)
    {
        server_ = std::make_unique<ServerNode>(uri);

        dispatcher_.RegisterHandler<transport::RequestCode::REGISTER_ROUTEINFO, transport::RegisterRouteInfoRequest, transport::RegisterRouteInfoResponse>(
                std::bind(&NameSrvController::ProcessRegisterRouteInfoRequest, this, std::placeholders::_1));

        dispatcher_.RegisterHandler<transport::RequestCode::QUERY_ROUTEINFO_BY_TOPIC, transport::QueryRouteInfoRequest, transport::QueryRouteInfoResponse>(
                std::bind(&NameSrvController::ProcessQueryRouteInfoRequest, this, std::placeholders::_1));

        dispatcher_.RegisterHandler<transport::RequestCode::QUERY_BROKER_CLUSTER_INFO, transport::QueryBrokerClusterInfoRequest, transport::QueryBrokerClusterInfoResponse>(
                std::bind(&NameSrvController::ProcessQueryBrokerClusterInfoRequest, this, std::placeholders::_1));
    }

    NameSrvController::~NameSrvController()
    {
        Stop();
    }

    bool NameSrvController::Start()
    {
        auto handler = [this]()
        {
            Bytes requestCmdBytes = server_->RecvRequest();
            auto requestCmd = ProtocolCodec<transport::RequestCommand>::Decode(requestCmdBytes);
            auto replyCmd = ProcessRequest(requestCmd);
            if(replyCmd.has_value())
            {
                server_->SendResponse(ProtocolCodec<transport::ReplyCommand>::Encode(replyCmd.value()));
            }
            // LOG_DEBUG("namesrv发送响应的大小%d", responseBytes.size());
        };
        reactor_.Add(*server_->GetSocket(), handler, zmqpp::poller::poll_in);
        reactor_.Start();
    }

    bool NameSrvController::Stop()
    {
    }

    std::optional<transport::ReplyCommand> NameSrvController::ProcessRequest(const transport::RequestCommand &requestCmd)
    {
        return dispatcher_.Process(requestCmd);
    }


    transport::RegisterRouteInfoResponse NameSrvController::ProcessRegisterRouteInfoRequest(const transport::RegisterRouteInfoRequest &request)
    {
        LOG_DEBUG("namesrv处理路由注册请求");
        std::map<std::string, routeinfo::TopicData> topicDataTable;
        for (const auto &pair : request.topic_data_table())
        {
            topicDataTable[pair.first] = pair.second;
            // LOG_DEBUG("queueNum %d", pair.second.queue_num());
        }
        std::string status = routeInfoManager_.RegisterRouteInfo(request.cluster_name(), request.broker_addr(), request.broker_name(), request.broker_id(), topicDataTable);
        transport::RegisterRouteInfoResponse response;
        response.set_code(transport::ResponseCode::SUCCESS);
        return response;
    }

    transport::UnRegisterRouteInfoResponse NameSrvController::ProcessUnRegisterRouteRequest(const transport::UnRegisterRouteInfoRequest &request)
    {
    }

    transport::QueryRouteInfoResponse NameSrvController::ProcessQueryRouteInfoRequest(const transport::QueryRouteInfoRequest &request)
    {
        LOG_DEBUG("namesrv处理路由查询请求");
        routeinfo::TopicRouteInfo topicRouteInfo = routeInfoManager_.QueryRouteInfoByTopic(request.topic());
        transport::QueryRouteInfoResponse response;
        response.set_topic(request.topic());
        response.mutable_topic_route_info()->CopyFrom(topicRouteInfo);
        return response;
    }

    transport::QueryBrokerClusterInfoResponse NameSrvController::ProcessQueryBrokerClusterInfoRequest(const transport::QueryBrokerClusterInfoRequest &request)
    {
        routeinfo::ClusterInfo clusterInfo = routeInfoManager_.GetAllClusterInfo();
        transport::QueryBrokerClusterInfoResponse response;
        response.mutable_cluster_info()->CopyFrom(clusterInfo);
        if (!clusterInfo.broker_addr_table_size() && !clusterInfo.cluster_addr_table_size())
        {
            response.set_code(transport::ResponseCode::FAILED);
        }
        else
        {
            response.set_code(transport::ResponseCode::SUCCESS);
        }

        return response;
    }

    void NameSrvController::ProcessHeartbeatMessage()
    {
    }

}
